using System;
using System.Reflection.Emit;
using Pine.Core;
using Pine.SourceParser.Tree;

namespace Pine.CodeGen
{
	public class ForStatementCodeGenerator
	{
		public static void GenerateBytecode(Context ctx, Statement stmt)
		{
			ForStatement forStmt = (ForStatement) stmt;
			
			Label begin = ctx.il.DefineLabel();
			Label end = ctx.il.DefineLabel();
			Label continueLabel = ctx.il.DefineLabel();
			
			Context forCtx = CodeUtilities.MakeWhileContext(ctx, forStmt.Name, continueLabel, end);
			if (forStmt.Begin != null)
				forStmt.Begin.GenerateBytecode(forCtx);
			
			ctx.il.MarkLabel(begin);
			
			//Now, handle condition
			if (forStmt.Condition != null) {
				LocalBuilder result = forCtx.il.DeclareLocal(typeof(Value));
				forStmt.Condition.GenerateBytecode(forCtx, result);
				forCtx.il.Emit(OpCodes.Ldloc, result);
				forCtx.il.Emit(OpCodes.Callvirt, typeof(Value).GetMethod("ToBoolean"));
				forCtx.il.Emit(OpCodes.Brfalse, end);
			}
			
			//Now, handle content
			forStmt.Content.GenerateBytecode(forCtx);
			
			ctx.il.MarkLabel(continueLabel);
			
			if (forStmt.End != null) {
				forStmt.End.GenerateBytecode(forCtx);
			}
			
			forCtx.il.Emit(OpCodes.Br, begin);
			
			ctx.il.MarkLabel(end);
		}
	}
}

